package com.rq.shuduapp;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    TextView[][] childs = new TextView[rules.length()][rules.length()];
    RelativeLayout fl;
    FrameLayout showPan;
    int sqrWidth = AppUtils.getScreenWidth() / 9;
    int focusX = -1, focusY = -1;
    TextView tvShow;
    Calculate2 mCalculate;

//    private final static Object[][] que = new Object[][]{
//           {0, 0, 0, 0, 0, 0, 4, 0, 1},//{0, 8, 0, 0, 0, 0, 4, 0, 1},//{0, 8, 0, 0, 0, 0, 4, 0, 1},//{0, 0, 0, 0, 0, 0, 4, 0, 1},//{0, 0, 7, 0, 2, 0, 0, 0, 1},//{0, 8, 0, 9, 0, 0, 0, 3, 0},// {9, 0, 0, 0, 2, 0, 4, 0, 1},  //{0, 0, 6, 3, 2, 5, 0, 0, 1},    //
//           {3, 4, 0, 1, 0, 0, 0, 0, 8},//{3, 4, 0, 1, 0, 0, 0, 0, 8},//{3, 4, 0, 1, 0, 0, 0, 0, 8},//{3, 4, 0, 1, 0, 0, 0, 0, 8},//{3, 0, 0, 1, 5, 7, 0, 2, 0},//{0, 0, 9, 1, 0, 0, 0, 0, 0},// {0, 0, 5, 0, 9, 0, 0, 2, 0},  //{3, 0, 0, 8, 1, 0, 0, 0, 5},    //
//           {0, 2, 1, 0, 0, 4, 0, 0, 0},//{0, 2, 1, 0, 0, 4, 0, 0, 7},//{0, 2, 1, 0, 0, 4, 0, 0, 7},//{0, 2, 1, 0, 0, 4, 0, 0, 0},//{0, 2, 1, 0, 0, 4, 0, 9, 7},//{6, 0, 0, 0, 0, 0, 5, 0, 7},// {0, 4, 0, 1, 0, 0, 0, 9, 7},  //{1, 9, 2, 4, 7, 6, 3, 0, 8},    //
//           {8, 0, 0, 5, 0, 0, 1, 7, 0},//{8, 9, 0, 5, 0, 0, 1, 7, 0},//{8, 9, 0, 5, 0, 0, 1, 7, 0},//{8, 0, 0, 5, 0, 0, 1, 7, 0},//{0, 0, 2, 0, 0, 3, 0, 7, 0},//{0, 0, 2, 5, 4, 0, 0, 0, 6},// {5, 0, 0, 0, 0, 1, 0, 0, 0},  //{0, 0, 0, 4, 1, 3, 0, 0, 9},    //
//           {0, 3, 0, 7, 1, 0, 0, 0, 0},//{0, 3, 0, 7, 1, 0, 0, 0, 0},//{0, 3, 0, 7, 1, 0, 8, 0, 0},//{0, 3, 0, 7, 1, 0, 0, 0, 0},//{0, 3, 0, 7, 1, 0, 8, 0, 0},//{0, 3, 0, 0, 0, 2, 0, 0, 0},// {0, 0, 0, 0, 0, 0, 0, 0, 2},  //{6, 0, 0, 0, 0, 0, 0, 0, 2},    //
//           {1, 7, 0, 6, 0, 0, 2, 0, 3},//{1, 7, 0, 6, 0, 0, 2, 0, 3},//{1, 7, 0, 6, 0, 0, 2, 0, 3},//{1, 7, 0, 6, 0, 0, 2, 0, 3},//{1, 0, 5, 0, 0, 9, 0, 4, 0},//{1, 7, 0, 0, 0, 0, 0, 0, 3},// {4, 0, 0, 5, 7, 0, 3, 0, 9},  //{0, 0, 5, 0, 2, 8, 0, 0, 0},    //
//           {0, 0, 0, 2, 0, 1, 7, 0, 0},//{0, 5, 3, 2, 6, 1, 7, 8, 0},//{9, 5, 3, 2, 6, 1, 7, 8, 4},//{0, 0, 0, 2, 0, 1, 7, 0, 0},//{0, 5, 0, 2, 6, 1, 0, 8, 4},//{0, 0, 3, 0, 0, 0, 7, 0, 4},// {0, 5, 3, 0, 0, 2, 1, 8, 0},  //{0, 8, 0, 0, 0, 0, 1, 2, 3},    //
//           {2, 1, 0, 0, 0, 0, 9, 6, 0},//{2, 1, 0, 0, 0, 0, 9, 6, 0},//{2, 1, 0, 0, 0, 0, 9, 6, 5},//{2, 1, 0, 0, 0, 0, 9, 6, 0},//{2, 0, 0, 3, 7, 0, 0, 0, 0},//{2, 0, 0, 3, 0, 8, 0, 6, 0},// {0, 0, 0, 0, 0, 0, 0, 0, 0},  //{0, 0, 4, 0, 0, 0, 5, 9, 7},    //
//           {0, 6, 0, 0, 9, 5, 3, 1, 2}///{0, 6, 0, 0, 9, 5, 3, 1, 2} //{0, 6, 0, 0, 9, 5, 3, 1, 2}///{0, 6, 0, 0, 9, 5, 3, 1, 2}///{7, 0, 8, 4, 0, 5, 0, 1, 2}///{0, 0, 0, 0, 0, 0, 0, 0, 0} // {0, 0, 2, 8, 0, 0, 0, 0, 3}   //{5, 0, 0, 0, 3, 0, 6, 0, 4}     //
//    };

    //多个解
    private final static Object[][] que = new Object[][]{
//            {4, 0, 0, 0, 3, 0, 0, 0, 0},//
//            {0, 5, 6, 0, 0, 0, 7, 0, 0},//
//            {0, 2, 0, 0, 0, 8, 0, 9, 5},//
//            {0, 0, 0, 0, 4, 0, 0, 2, 6},//
//            {0, 0, 0, 0, 0, 3, 1, 0, 0},//
//            {0, 0, 0, 0, 8, 0, 0, 4, 9},//
//            {0, 4, 0, 0, 0, 1, 0, 3, 2},//
//            {0, 6, 1, 0, 0, 0, 5, 0, 0},//
//            {3, 0, 0, 0, 2, 0, 0, 0, 0}///
            {1, 0, 0, 0},
            {0, 0, 0, 0},
            {0, 0, 0, 0},
            {0, 0, 0, 0},
    };
//    private static String rules = "123456789";
    private static String rules = "1234";


    static {
        Object[][] copy = new Object[rules.length()][rules.length()];
        for (int i = 0; i < rules.length(); i++) {
            for (int k = 0; k < rules.length(); k++) {
                copy[i][k] = que[k][i];
            }
        }
        for (int i = 0; i < rules.length(); i++) {
            for (int k = 0; k < rules.length(); k++) {
                que[i][k] = copy[i][k];
            }
        }
    }

    View.OnTouchListener mTouch = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            LOG.e("MainActivity", "34:" + v.getX() + "," + v.getY());
//                String tag = (String) v.getTag();
            focusX = Math.min((int) (event.getX() / sqrWidth), rules.length() - 1);
            focusY = Math.min((int) (event.getY() / sqrWidth), rules.length() - 1);
            refuseView();
            return true;
        }
    };

    private void refuseView() {
        for (int i = 0; i < rules.length(); i++) {
            for (int k = 0; k < rules.length(); k++) {
                if (focusX == i && focusY == k) {
                    childs[i][k].setBackgroundColor(Color.GRAY);
                } else {
                    childs[i][k].setBackgroundColor(Color.WHITE);
                }
            }
        }
        tvShow.setText((focusX + 1) + "," + (focusY + 1) + "---->" + childs[focusX][focusY].getText());
    }


    public void reSet(View view) {
        for (int i = 0; i < rules.length(); i++) {
            for (int k = 0; k < rules.length(); k++) {
                System.out.print(que[i][k] + " ");
            }
            System.out.println("");
        }

        mCalculate = new Calculate2(que, rules);
        initData();
        hasNext = true;
    }

    private void setData2View(String con) {
        if (focusX > -1 && focusY > -1) {
            if (TextUtils.isEmpty(childs[focusX][focusY].getText())) {
                setData2View(focusX, focusY, con, Color.BLUE);
            } else {
                if (childs[focusX][focusY].getCurrentTextColor() == Color.BLUE) {
                    setData2View(focusX, focusY, con);
                }
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fl = findViewById(R.id.out);
        showPan = findViewById(R.id.showPan);
        showPan.setOnTouchListener(mTouch);
        tvShow = findViewById(R.id.showText);
        mCalculate = new Calculate2(que, rules);
        setView();
        initData();
        setLine();
        LinearLayout ctr = findViewById(R.id.ctr);
        for (int i = 0; i < ctr.getChildCount(); i++) {
            final int finalI = i;
            ctr.getChildAt(i).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    setData2View(String.valueOf(finalI + 1));
                }
            });
        }
    }

    private void initData() {
        for (int i = 0; i < rules.length(); i++) {
            for (int k = 0; k < rules.length(); k++) {
                if (!mCalculate.isEmpty(que[i][k], rules)) {
                    setData2View(i, k, String.valueOf(que[i][k]));
                } else {
                    setData2View(i, k, "");
                }
            }
        }
    }

    private void setView() {
        int mar = AppUtils.getScreenWidth() / 9;
        for (int i = 0; i < rules.length(); i++) {
            for (int k = 0; k < rules.length(); k++) {
                TextView tv = new TextView(this);
                tv.setGravity(Gravity.CENTER);
                tv.setTextColor(Color.BLACK);
                tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
                FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(mar, mar);
                flp.leftMargin = i * mar;
                flp.topMargin = k * mar;
                tv.setTag(i + "," + k);
                showPan.addView(tv, flp);
                childs[i][k] = tv;
            }
        }
    }

    private void setLine() {
        int width = AppUtils.getScreenWidth();
        int sqr = (int) Math.sqrt(rules.length());
        for (int i = 0; i <= rules.length(); i++) {
            View hLIne = new View(this);
            View vLIne = new View(this);
            hLIne.setBackgroundColor(Color.BLACK);
            vLIne.setBackgroundColor(Color.BLACK);
            RelativeLayout.LayoutParams flp = null;
            RelativeLayout.LayoutParams vflp = null;
            if (i % sqr == 0) {
                flp = new RelativeLayout.LayoutParams(width, 3);
                vflp = new RelativeLayout.LayoutParams(3, width);
            } else {
                flp = new RelativeLayout.LayoutParams(width, 1);
                vflp = new RelativeLayout.LayoutParams(1, width);
            }
            flp.topMargin = width * i / 9;
            vflp.leftMargin = width * i / 9;
            fl.addView(hLIne, flp);
            fl.addView(vLIne, vflp);
        }
    }

    private void setData2View(int x, int y, String con) {
        setData2View(x, y, con, Color.BLACK);
    }

    private void setData2View(final int x, final int y, final String con, final int color) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (con != null) {
                    childs[x][y].setText(con);
                }
                childs[x][y].setTextColor(color);
            }
        });
    }

    private boolean hasNext = true;
    List<String> steps = new ArrayList<>();

    private void setHere() {
        for (int i = 0; i < rules.length(); i++) {
            for (int k = 0; k < rules.length(); k++) {
                que[i][k] = childs[i][k].getText();
            }
        }
        mCalculate = new Calculate2(que, rules);
    }

    public void stepOne(View view) {
        setHere();
        final Row2 item = mCalculate.getNext();
        if (item != null) {
//            System.out.println("MainActivity-STEP." + item.getWriteTime() + "(" + item.loc() + "):" + item.getValue());
            setData2View(item.getX(), item.getY(), String.valueOf(item.getValue()), Color.RED);
            steps.add(item.loc());
        }
    }

    public void autoCalc(View view) {
        hasNext = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (hasNext) {
//                    final Row2 item = mCalculate.getNext();
//                    if (item != null) {
////                        System.out.println("MainActivity-STEP." + item.getWriteTime() + "(" + item.locTxt() + "):" + item.getValue());
//                        setData2View(item.getX(), item.getY(), String.valueOf(item.getValue()), Color.RED);
//                        steps.add(item.loc());
//                    } else {
//                        hasNext = false;
//                    }
//                    if (hasNext) {
//                        try {
//                            Thread.sleep(80);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }

                    Row2 item = mCalculate.getNext();
                    if (item == null) {
                        if (mCalculate.isOk()) {
                            hasNext = false;
                        } else if (mCalculate.rollBack()) {
                            Row2[][] guess = mCalculate.getGuessRes();
                            for (int x = 0; x < guess.length; x++) {
                                for (int y = 0; y < guess[x].length; y++) {
                                    if (guess[x][y].guessValueRes != null && guess[x][y].guessValueRes.length() > 0)
                                        setData2View(guess[x][y].getX(), guess[x][y].getY(), guess[x][y].value, Color.BLUE);
                                }
                            }
                            hasNext = true;
                            continue;
                        }
                        hasNext = false;
//                        System.err.println(item.writeTime + " 计算:" + item.locTxt() + ">" + item.value);
                    } else {
                        setData2View(item.getX(), item.getY(), String.valueOf(item.getValue()), Color.RED);
                    }
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                mCalculate.showGuessTimes();
            }
        }).start();
    }

    public static String list2Str(List<String> con) {
        if (con != null && con.size() > 0) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < con.size(); i++) {
                sb.append(con.get(i)).append(">  ");
            }
            return sb.toString();
        }
        return "";
    }

    public void clearOne(View view) {
        if (steps.size() == 0) return;
        String loc = steps.remove(steps.size() - 1);
        int x = Integer.parseInt(loc.split(",")[0]);
        int y = Integer.parseInt(loc.split(",")[1]);
        setData2View(x, y, "");
    }

}
